// 定义已经加载的资源信息接口
interface LoadedResource {
  url: string;
  isCss: boolean;
}

class CDNLoader {
  // 用于存储已经加载的资源信息
  private static loadedResources: LoadedResource[] = [];

  // 加载CSS文件
  static loadCss(url: string): Promise<void> {
    return new Promise((resolve, reject) => {
      // 检查该CSS文件是否已经被引入过，如果是就直接返回成功
      if (this.isResourceLoaded(url, true)) {
        resolve();
        return;
      }

      // 创建link元素，并设置类型和href属性
      const link = document.createElement('link');
      link.type = 'text/css';
      link.rel = 'stylesheet';

      // 设置成功和失败的回调函数
      link.onload = () => {
        // 记录已经加载的资源信息
        const resource = { url, isCss: true };
        this.loadedResources.push(resource);
        resolve();
      };
      link.onerror = () => reject();

      // 设置CSS文件的URL地址，并将link元素添加到head元素中
      link.href = url;
      document.head.appendChild(link);
    });
  }

  // 加载JS文件
  static loadScript(url: string): Promise<void> {
    return new Promise((resolve, reject) => {
      // 检查该JS文件是否已经被引入过，如果是就直接返回成功
      if (this.isResourceLoaded(url, false)) {
        resolve();
        return;
      }

      // 创建script元素，并设置类型和src属性
      const script = document.createElement('script');
      script.type = 'text/javascript';
      script.async = true;

      // 设置成功和失败的回调函数
      script.onload = () => {
        // 记录已经加载的资源信息
        const resource = { url, isCss: false };
        this.loadedResources.push(resource);
        resolve();
      };
      script.onerror = () => reject();

      // 设置JS文件的URL地址，并将script元素添加到head元素中
      script.src = url;
      document.head.appendChild(script);
    });
  }

  // 销毁已经加载的CSS或JS文件
  static destroyLoadedResources(url: string): void {
    // 找到要销毁的资源信息
    const resourcesToDestroy = this.loadedResources.filter((resource) => resource.url === url);

    // 遍历要销毁的资源信息
    resourcesToDestroy.forEach((resource) => {
      // 找到对应的link或script元素，并将其从文档中移除
      const elements = document.head.querySelectorAll(resource.isCss ? `link[href="${url}"]` : `script[src="${url}"]`);
      elements.forEach((element) => element.remove());
    });

    // 从loadedResources数组中删除要销毁的资源信息
    this.loadedResources = this.loadedResources.filter((resource) => resource.url !== url);
  }

  // 检查给定的CSS或JS文件是否已经被引入过
  private static isResourceLoaded(url: string, isCss: boolean): boolean {
    const resources = this.loadedResources.filter((resource) => resource.url === url && resource.isCss === isCss);
    return resources.length > 0;
  }
}

export default CDNLoader;
